import { PIECE_TYPES, COLORS, BOARD_CONFIG } from './constants.js';

// 棋子基类
export class Piece {
    constructor(type, color, row, col) {
        this.type = type;
        this.color = color;
        this.row = row;
        this.col = col;
        this.hasMoved = false; // 标记棋子是否移动过
    }
    
    // 获取棋子的中文表示
    getChineseName() {
        const names = {
            [PIECE_TYPES.ROOK]: '车',
            [PIECE_TYPES.HORSE]: '马',
            [PIECE_TYPES.ELEPHANT]: this.color === COLORS.RED ? '相' : '象',
            [PIECE_TYPES.ADVISOR]: this.color === COLORS.RED ? '仕' : '士',
            [PIECE_TYPES.GENERAL]: this.color === COLORS.RED ? '帅' : '将',
            [PIECE_TYPES.CANNON]: '炮',
            [PIECE_TYPES.PAWN]: this.color === COLORS.RED ? '兵' : '卒'
        };
        return names[this.type];
    }
    
    // 检查移动是否合法的基方法（由子类实现）
    isValidMove(board, toRow, toCol) {
        // 检查目标位置是否在棋盘范围内
        if (toRow < 0 || toRow >= BOARD_CONFIG.ROWS || toCol < 0 || toCol >= BOARD_CONFIG.COLS) {
            return false;
        }
        
        // 检查目标位置是否有自己的棋子
        const targetPiece = board.getPieceAt(toRow, toCol);
        if (targetPiece && targetPiece.color === this.color) {
            return false;
        }
        
        return true;
    }
    
    // 获取所有可能的移动位置
    getPossibleMoves(board) {
        const moves = [];
        
        for (let row = 0; row < BOARD_CONFIG.ROWS; row++) {
            for (let col = 0; col < BOARD_CONFIG.COLS; col++) {
                if (this.isValidMove(board, row, col)) {
                    // 模拟移动并检查是否会导致自己被将军
                    const simulatedBoard = board.clone();
                    const capturedPiece = simulatedBoard.movePiece(this.row, this.col, row, col);
                    
                    if (!simulatedBoard.isInCheck(this.color)) {
                        moves.push({ row, col });
                    }
                    
                    // 恢复棋盘状态
                    simulatedBoard.movePiece(row, col, this.row, this.col);
                    if (capturedPiece) {
                        simulatedBoard.setPieceAt(row, col, capturedPiece);
                    }
                }
            }
        }
        
        return moves;
    }
    
    // 克隆棋子
    clone() {
        return new Piece(this.type, this.color, this.row, this.col);
    }
}

// 车
export class Rook extends Piece {
    constructor(color, row, col) {
        super(PIECE_TYPES.ROOK, color, row, col);
    }
    
    isValidMove(board, toRow, toCol) {
        if (!super.isValidMove(board, toRow, toCol)) {
            return false;
        }
        
        // 车只能直线移动
        if (this.row !== toRow && this.col !== toCol) {
            return false;
        }
        
        // 检查路径上是否有棋子阻挡
        if (this.row === toRow) {
            // 水平移动
            const startCol = Math.min(this.col, toCol) + 1;
            const endCol = Math.max(this.col, toCol);
            for (let col = startCol; col < endCol; col++) {
                if (board.getPieceAt(this.row, col)) {
                    return false;
                }
            }
        } else {
            // 垂直移动
            const startRow = Math.min(this.row, toRow) + 1;
            const endRow = Math.max(this.row, toRow);
            for (let row = startRow; row < endRow; row++) {
                if (board.getPieceAt(row, this.col)) {
                    return false;
                }
            }
        }
        
        return true;
    }
}

// 马
export class Horse extends Piece {
    constructor(color, row, col) {
        super(PIECE_TYPES.HORSE, color, row, col);
    }
    
    isValidMove(board, toRow, toCol) {
        if (!super.isValidMove(board, toRow, toCol)) {
            return false;
        }
        
        const rowDiff = Math.abs(toRow - this.row);
        const colDiff = Math.abs(toCol - this.col);
        
        // 马走日字
        if (!((rowDiff === 1 && colDiff === 2) || (rowDiff === 2 && colDiff === 1))) {
            return false;
        }
        
        // 检查马腿是否被绊住
        let legRow, legCol;
        if (rowDiff === 2) {
            // 垂直移动两格，水平移动一格
            legRow = this.row + (toRow > this.row ? 1 : -1);
            legCol = this.col;
        } else {
            // 水平移动两格，垂直移动一格
            legRow = this.row;
            legCol = this.col + (toCol > this.col ? 1 : -1);
        }
        
        if (board.getPieceAt(legRow, legCol)) {
            return false; // 马腿被绊住
        }
        
        return true;
    }
}

// 象/相
export class Elephant extends Piece {
    constructor(color, row, col) {
        super(PIECE_TYPES.ELEPHANT, color, row, col);
    }
    
    isValidMove(board, toRow, toCol) {
        if (!super.isValidMove(board, toRow, toCol)) {
            return false;
        }
        
        // 象不能过河
        if ((this.color === COLORS.RED && toRow < BOARD_CONFIG.RIVER_TOP) ||
            (this.color === COLORS.BLACK && toRow > BOARD_CONFIG.RIVER_BOTTOM)) {
            return false;
        }
        
        const rowDiff = Math.abs(toRow - this.row);
        const colDiff = Math.abs(toCol - this.col);
        
        // 象走田字
        if (rowDiff !== 2 || colDiff !== 2) {
            return false;
        }
        
        // 检查象眼是否被塞住
        const eyeRow = (this.row + toRow) / 2;
        const eyeCol = (this.col + toCol) / 2;
        
        if (board.getPieceAt(eyeRow, eyeCol)) {
            return false; // 象眼被塞住
        }
        
        return true;
    }
}

// 士/仕
export class Advisor extends Piece {
    constructor(color, row, col) {
        super(PIECE_TYPES.ADVISOR, color, row, col);
    }
    
    isValidMove(board, toRow, toCol) {
        if (!super.isValidMove(board, toRow, toCol)) {
            return false;
        }
        
        // 士只能在九宫格内移动
        const isInPalace = (color, row, col) => {
            if (color === COLORS.RED) {
                return row >= BOARD_CONFIG.RED_PALACE_TOP && 
                       row <= BOARD_CONFIG.RED_PALACE_BOTTOM &&
                       col >= BOARD_CONFIG.PALACE_LEFT && 
                       col <= BOARD_CONFIG.PALACE_RIGHT;
            } else {
                return row >= BOARD_CONFIG.BLACK_PALACE_TOP && 
                       row <= BOARD_CONFIG.BLACK_PALACE_BOTTOM &&
                       col >= BOARD_CONFIG.PALACE_LEFT && 
                       col <= BOARD_CONFIG.PALACE_RIGHT;
            }
        };
        
        if (!isInPalace(this.color, toRow, toCol)) {
            return false;
        }
        
        const rowDiff = Math.abs(toRow - this.row);
        const colDiff = Math.abs(toCol - this.col);
        
        // 士只能斜走一格
        if (rowDiff !== 1 || colDiff !== 1) {
            return false;
        }
        
        return true;
    }
}

// 将/帅
export class General extends Piece {
    constructor(color, row, col) {
        super(PIECE_TYPES.GENERAL, color, row, col);
    }
    
    isValidMove(board, toRow, toCol) {
        // 特殊情况：将帅对面
        const oppositeGeneral = board.findGeneral(this.color === COLORS.RED ? COLORS.BLACK : COLORS.RED);
        if (oppositeGeneral && this.col === toCol && this.col === oppositeGeneral.col) {
            // 检查列上是否有其他棋子
            let hasObstacle = false;
            const startRow = Math.min(this.row, oppositeGeneral.row) + 1;
            const endRow = Math.max(this.row, oppositeGeneral.row);
            for (let row = startRow; row < endRow; row++) {
                if (board.getPieceAt(row, this.col)) {
                    hasObstacle = true;
                    break;
                }
            }
            
            if (!hasObstacle && toRow === oppositeGeneral.row) {
                return true; // 将帅对面，合法
            }
        }
        
        if (!super.isValidMove(board, toRow, toCol)) {
            return false;
        }
        
        // 将只能在九宫格内移动
        const isInPalace = (color, row, col) => {
            if (color === COLORS.RED) {
                return row >= BOARD_CONFIG.RED_PALACE_TOP && 
                       row <= BOARD_CONFIG.RED_PALACE_BOTTOM &&
                       col >= BOARD_CONFIG.PALACE_LEFT && 
                       col <= BOARD_CONFIG.PALACE_RIGHT;
            } else {
                return row >= BOARD_CONFIG.BLACK_PALACE_TOP && 
                       row <= BOARD_CONFIG.BLACK_PALACE_BOTTOM &&
                       col >= BOARD_CONFIG.PALACE_LEFT && 
                       col <= BOARD_CONFIG.PALACE_RIGHT;
            }
        };
        
        if (!isInPalace(this.color, toRow, toCol)) {
            return false;
        }
        
        const rowDiff = Math.abs(toRow - this.row);
        const colDiff = Math.abs(toCol - this.col);
        
        // 将只能走一步（上、下、左、右）
        if (!((rowDiff === 1 && colDiff === 0) || (rowDiff === 0 && colDiff === 1))) {
            return false;
        }
        
        return true;
    }
}

// 炮
export class Cannon extends Piece {
    constructor(color, row, col) {
        super(PIECE_TYPES.CANNON, color, row, col);
    }
    
    isValidMove(board, toRow, toCol) {
        if (!super.isValidMove(board, toRow, toCol)) {
            return false;
        }
        
        // 炮只能直线移动
        if (this.row !== toRow && this.col !== toCol) {
            return false;
        }
        
        const targetPiece = board.getPieceAt(toRow, toCol);
        let obstacleCount = 0;
        
        if (this.row === toRow) {
            // 水平移动
            const startCol = Math.min(this.col, toCol) + 1;
            const endCol = Math.max(this.col, toCol) - 1;
            for (let col = startCol; col <= endCol; col++) {
                if (board.getPieceAt(this.row, col)) {
                    obstacleCount++;
                }
            }
        } else {
            // 垂直移动
            const startRow = Math.min(this.row, toRow) + 1;
            const endRow = Math.max(this.row, toRow) - 1;
            for (let row = startRow; row <= endRow; row++) {
                if (board.getPieceAt(row, this.col)) {
                    obstacleCount++;
                }
            }
        }
        
        // 炮翻山吃子需要一个炮架，否则不能有炮架
        if (targetPiece) {
            return obstacleCount === 1; // 吃子需要一个炮架
        } else {
            return obstacleCount === 0; // 移动不能有炮架
        }
    }
}

// 卒/兵
export class Pawn extends Piece {
    constructor(color, row, col) {
        super(PIECE_TYPES.PAWN, color, row, col);
    }
    
    isValidMove(board, toRow, toCol) {
        if (!super.isValidMove(board, toRow, toCol)) {
            return false;
        }
        
        const direction = this.color === COLORS.RED ? -1 : 1; // 红兵向上，黑卒向下
        const rowDiff = toRow - this.row;
        const colDiff = Math.abs(toCol - this.col);
        
        // 只能走一步
        if (Math.abs(rowDiff) > 1 || colDiff > 1) {
            return false;
        }
        
        // 前进
        if (rowDiff === direction && colDiff === 0) {
            return true;
        }
        
        // 过河后可以横向移动
        const hasCrossedRiver = (this.color === COLORS.RED && this.row <= BOARD_CONFIG.RIVER_TOP) ||
                                (this.color === COLORS.BLACK && this.row >= BOARD_CONFIG.RIVER_BOTTOM);
        
        if (hasCrossedRiver && rowDiff === 0 && colDiff === 1) {
            return true;
        }
        
        return false;
    }
}

// 创建棋子的工厂函数
export function createPiece(type, color, row, col) {
    switch (type) {
        case PIECE_TYPES.ROOK:
            return new Rook(color, row, col);
        case PIECE_TYPES.HORSE:
            return new Horse(color, row, col);
        case PIECE_TYPES.ELEPHANT:
            return new Elephant(color, row, col);
        case PIECE_TYPES.ADVISOR:
            return new Advisor(color, row, col);
        case PIECE_TYPES.GENERAL:
            return new General(color, row, col);
        case PIECE_TYPES.CANNON:
            return new Cannon(color, row, col);
        case PIECE_TYPES.PAWN:
            return new Pawn(color, row, col);
        default:
            throw new Error(`未知的棋子类型: ${type}`);
    }
}